package com.party.util.easyexcel;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.party.util.easyexcel.listener.PartitionDataListener;
import com.party.util.easyexcel.model.ExcelHeader;
import com.party.util.easyexcel.style.GeneralCellStyleStrategy;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * EasyExcel工具
 *
 * @author gcx
 * @date 2019/12/19
 */
public class ExcelUtils {

    private ExcelUtils() {
    }

    public static ExcelTypeEnum excelType = ExcelTypeEnum.XLSX;

    /**
     * 将excel解析为pojo对象(返回全部)
     *
     * @param inputStream
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> parse(InputStream inputStream, Class<T> clazz) {
        return EasyExcel.read(inputStream).head(clazz).sheet().doReadSync();
    }

    /**
     * 分片处理excel解析对象
     *
     * @param inputStream
     * @param clazz
     * @param consumer    回调接口
     * @param size        分片大小
     * @param <T>
     */
    public static <T> void parsePartition(InputStream inputStream, Class<T> clazz, Consumer<List<T>> consumer, int size) {
        EasyExcel.read(inputStream, clazz, new PartitionDataListener<>(size, consumer)).sheet().doRead();
    }

    /**
     * 导出excel
     *
     * @param fileName
     * @param list
     * @param excelHeader
     * @param <T>
     * @throws Exception
     */
    @SuppressWarnings({"unchecked"})
    public static <T> void export(String fileName, List<T> list, ExcelHeader excelHeader) throws Exception {
        String timestamp = DateUtils.format(new Date(), "yyyyMMddHHmmss");
        fileName = URLEncoder.encode(fileName + timestamp + excelType.getValue(), "UTF-8");
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = attributes.getResponse();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        List<List<String>> headers = excelHeader.getHeaders();
        List<List<Object>> dataList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            List<Map> dataMapList = (List<Map>) (list.get(0) instanceof Map ? list : JSON.toJSON(list));
            dataMapList.forEach(map -> dataList.add(excelHeader.getKeys().stream()
                    .map((Function<String, Object>) map::get)
                    .collect(Collectors.toList())));
        }
        EasyExcel.write(response.getOutputStream())
                .registerWriteHandler(new GeneralCellStyleStrategy())
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 16, (short) 16))
                .head(headers).excelType(excelType).sheet().doWrite(dataList);
    }
}
